package com.friend.common.aspect;

import com.friend.domain.question.Question;
import com.friend.domain.question.es.QuestionES;
import com.friend.integration.elasticsearch.QuestionRepository;
import com.friend.manager.QuestionCacheManager;
import com.friend.mapper.question.QuestionMapper;
import com.friend.util.QuestionConverter;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;


@Aspect
@Component
@Slf4j
public class QuestionChangeAspect {
    
    @Autowired
    private QuestionMapper questionMapper;
    
    @Autowired
    private QuestionRepository questionRepository;
    
    @Autowired
    private QuestionCacheManager questionCacheManager;
    
    // 精确拦截QuestionMapper的增删改方法
    @Pointcut("execution(* com.friend.mapper.question.QuestionMapper.insert*(..)) || " +
              "execution(* com.friend.mapper.question.QuestionMapper.update*(..)) || " +
              "execution(* com.friend.mapper.question.QuestionMapper.delete*(..))")
    public void questionChangeMethods() {}
    
    @AfterReturning(pointcut = "questionChangeMethods()", returning = "result")
    public void afterQuestionChange(JoinPoint joinPoint, Object result) {
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        
        // 提取questionId
        Long questionId = extractQuestionId(args, methodName);
        
        if (questionId != null) {
            processESUpdate(questionId, methodName);
        } else {
            log.warn("无法提取questionId: method={}, args={}", methodName, args);
        }
    }
    
    @Async("taskExecutor")
    public void processESUpdate(Long questionId, String methodName) {
        try {
            if (methodName.startsWith("delete")) {
                // 删除ES中的记录
                questionRepository.deleteById(questionId);
            } else {
                // 插入或更新：重新查询并同步到ES
                Question question = questionMapper.selectById(questionId);
                if (question != null) {
                    QuestionES questionES = QuestionConverter.toQuestionES(question);
                    questionRepository.save(questionES);
                } else {
                    log.warn("数据库查询失败，无法同步到ES: questionId={}", questionId);
                }
            }
            
            // 同时更新Redis缓存
            try {
                questionCacheManager.refreshCache();
            } catch (Exception cacheException) {
                log.error("Redis缓存刷新失败: questionId={}", questionId, cacheException);
            }
            
        } catch (Exception e) {
            log.error("ES同步失败: questionId={}", questionId, e);
        }
    }
    
    private Long extractQuestionId(Object[] args, String methodName) {
        if (args.length == 0) return null;
        
        if (methodName.startsWith("insert")) {
            // insert方法：参数是Question对象
            if (args[0] instanceof Question) {
                return ((Question) args[0]).getQuestionId();
            }
        } else if (methodName.startsWith("update")) {
            // update方法：参数可能是Question对象或ID
            if (args[0] instanceof Question) {
                return ((Question) args[0]).getQuestionId();
            } else if (args[0] instanceof Long) {
                return (Long) args[0];
            }
        } else if (methodName.startsWith("delete")) {
            // delete方法：参数通常是ID
            if (args[0] instanceof Long) {
                return (Long) args[0];
            }
        }
        
        return null;
    }
}
